----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date:    12:25:16 09/27/2013 
-- Design Name: 
-- Module Name:    twos_complement_64 - Behavioral 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description: 
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

-- control: 00 - don't complement
-- control: 01 - complement 63 downto 32
-- control: 10 - complement 63 downto 0
entity twos_complement_64 is
	port ( 	dataIn : in STD_LOGIC_VECTOR(63 downto 0);
				control : in STD_LOGIC_VECTOR(1 downto 0);
				dataOut : out STD_LOGIC_VECTOR(63 downto 0));
end twos_complement_64;

architecture Behavioral of twos_complement_64 is
	component adder_32 
		 port ( a : in  STD_LOGIC_VECTOR (31 downto 0);
				  b : in  STD_LOGIC_VECTOR (31 downto 0);
				  carryIn : in  STD_LOGIC;
				  sum : out  STD_LOGIC_VECTOR (31 downto 0);
				  carryOut : out  STD_LOGIC);
	end component;
	signal a1, b1, a2, b2 : STD_LOGIC_VECTOR(31 downto 0);
	signal sum1, sum2 : STD_LOGIC_VECTOR(31 downto 0);
	signal carryIn1, carryOut1, carryIn2, carryOut2 : STD_LOGIC;
begin
	adder1 : adder_32 port map(a1, b1, carryIn1, sum1, carryOut1);
	adder2 : adder_32 port map(a2, b2, carryIn2, sum2, carryOut2);
	
	a2 <= dataIn(63 downto 32) when control = "00" else
			NOT(dataIn(63 downto 32));
	
	a1 <= NOT(dataIn(31 downto 0)) when control = "10" else
			dataIn(31 downto 0);
			
	b2 <= X"00000000";
	b1 <= X"00000000";
	
	carryIn1 <= '1' when control = "10" else
					'0';
	carryIn2 <= carryOut1 when control = "10" else
					'1' when control = "01" else
					'0';
					
	dataOut <= sum2 & sum1;

end Behavioral;

